package org.payeco.risk.common;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.jeasy.rules.api.Rule;
import org.payeco.risk.annotation.PutRiskRule;
import org.payeco.risk.api.PayecoRule;
import org.payeco.risk.entity.PayecoRiskRule;

import com.google.common.base.Objects;

public enum PayecoRiskOpRuleType {

	BANK("BANK", new Object());

	private String rulename;
	private Object rule;

	PayecoRiskOpRuleType(String rulename, Object rule) {
		this.rulename = rulename;
		this.rule = rule;
	}

	public String getRulename() {
		return rulename;
	}

	public void setRulename(String rulename) {
		this.rulename = rulename;
	}

	public Object getRule() {
		return rule;
	}

	public void setRule(Rule rule) {
		this.rule = rule;
	}

	public static Object handler(String rulename) {
		PayecoRiskOpRuleType[] types = PayecoRiskOpRuleType.values();
		for (PayecoRiskOpRuleType type : types) {
			if (Objects.equal(rulename, type.getRulename())) {
				return type.getRule();
			}
		}
		return null;
	}

	public static Object handler(String rulename, PayecoRiskRule rulevalue) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		PayecoRiskOpRuleType[] types = PayecoRiskOpRuleType.values();
		for (PayecoRiskOpRuleType type : types) {
			if (Objects.equal(rulename, type.getRulename())) {
				if (type.getRule() instanceof PayecoRule) {
					PayecoRule risk = (PayecoRule) type.getRule();
					risk.setRiskRule(rulevalue);
					return risk;
				} else {
					Object o = type.getRule();
					Method method = type.getSetRiskRuleMethod();
					method.invoke(o, rulevalue);
					return o;
				}
			}
		}
		return null;
	}

	private Method getSetRiskRuleMethod() {
		Method[] methods = getMethods();
		for (Method method : methods) {
			if (method.isAnnotationPresent(PutRiskRule.class)) {
				return method;
			}
		}
		return null;
	}

	private Method[] getMethods() {
		return this.getRule().getClass().getMethods();
	}
}
